package com.ruoyi.law.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 字符串工具类
 */
public class StringUtil {
	private static String chars = "0123456789abcdefghijklmnopqrstuvwxyz"; // 用于小写的情况
	private static final String SYMBOLS = "0123456789"; // 数字

	private static final Random RANDOM = new SecureRandom();

	  
	/**
	 * 字节数组转换成十六进制字符串 String对象的getBytes()方法按照一定规则生成字节数组 然后使用new String(byte[]
	 * bs)方法复原(使用默认编码)
	 * 
	 * @param bs
	 * @return
	 */
	public static String bytesToHexString(final byte[] bs) {
		final StringBuffer sb = new StringBuffer(bs.length * 2);
		for (int i = 0; i < bs.length; i++) {
			// 保留后8位（防止负数的情况,负数有可能就是负数字节或者中文产生的负数字节）
			final String hex = Integer.toHexString(bs[i] & 0xFF);
			if (hex.length() < 2) {
				// Integer.toHexString(15)结果为F，所以需要加上0组成0F，也就是一个字节（8位）
				sb.append("0" + hex);
			} else {
				sb.append(hex);
			}
		}
		return sb.toString();
	}

	/**
	 * 指定字符在字符串中存在的数量
	 * 
	 * @param selectStr
	 *            查询字符
	 * @param targetStr
	 *            目标字符串
	 * @return num
	 */
	public static int findStrIndexOfCount(final String selectStr,
			final String targetStr) {
		final int selectLength = selectStr.length();
		final int targetLength = targetStr.length();
		if (selectLength > 0 && selectLength < targetLength) {
			return (targetLength - targetStr.replaceAll(selectStr, "").length())
					/ selectLength;
		}
		return -1;
	}

	public static String getBorrowNo(final long userId) {
		final SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		return df.format(new Date()) + "" + userId;
	}

	/**
	 * 根据字节数组和指定的编码格式生成字符串
	 * 
	 * @param bs
	 * @param charset
	 * @return
	 */
	public static String getString(final byte[] bs, final String charset) {
		String str = null;
		try {
			str = new String(bs, charset);
		} catch (final UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 十六进制字符串转成字节数组 十六进制字符串中用两个字符代表一个字节(8位)
	 * 
	 * @param str
	 * @return
	 */
	public static byte[] hexStringToBytes(final String str) {
		final int length = str.length() / 2;
		final byte[] bs = new byte[length];
		final char[] cs = str.toCharArray();
		for (int i = 0; i < bs.length; i++) {
			final int pos = i * 2;
			bs[i] = (byte) ((charToByte(cs[pos]) << 4)
					| charToByte(cs[pos + 1]));
		}
		return bs;
	}

	/**
	 * 判断字符串是否为空或者空字符串
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotNull(final String str) {
		return !isNull(str);
	}

	/**
	 * 判断字符串是否为空或者空字符串
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNull(final String str) {
		return str == null || str.trim().length() == 0 || "".equals(str)
				|| "null".equals(str);
	}

	/**
	 * 三位变两位（直接舍弃不是四舍五入）
	 * 
	 * @param threeBits
	 *            小数点后三位
	 * @return String
	 */
	public static String threeToTwoBits(final Double threeBits) {
		String twoBits = "";
		if (null != threeBits && isNotNull(String.valueOf(threeBits))) {
			twoBits = String.valueOf(
					Math.floor(Double.valueOf(threeBits) * 100d) / 100);
		}
		return twoBits;
	}

	/**
	 * 将指定字符串中所有包含三位数字的变成两位数字返回
	 * 
	 * @param msg
	 *            需要替换的字符串
	 * @return msg 替换完毕
	 */
	public static String threeToTwoBitsAll(String msg) {
		final int count = findStrIndexOfCount("元", msg);
		if (count > 0) {
			int index = msg.indexOf(".");
			int yuan = msg.indexOf("元");
			if (index > 0 && yuan > 0 && (yuan - index == 4)) {
				msg = msg.replace(msg.substring(index, yuan),
						msg.substring(index, yuan).substring(0, 3));
				for (int i = 0; i < count - 1; i++) {
					index = msg.indexOf(".", index + 1);
					yuan = msg.indexOf("元", yuan + 1);
					if (yuan - index == 4) {
						msg = msg.replace(msg.substring(index, yuan),
								msg.substring(index, yuan).substring(0, 3));
					}
				}
			}
		}
		return msg;
	}

	/**
	 * char类型转换成byte类型
	 */
	private static byte charToByte(final char c) {
		return (byte) chars.indexOf(c);
	}
	/**
	 *  验证密码格式 6~30位，除<(小于)、>(大于)都可以
	 * @param pwd 密码
	 * @return
	 */
	public static boolean passwordFormatCheck(String pwd){
	    // 密码验证规则
	    final String regEx =  "^[0-9a-zA-Z\\^!@#\\$%^&\\*\\(\\)_\\.\\+\\{\\}:\\|\\[\\]\\?]{6,30}$";
	    // 编译正则表达式
	    Pattern pattern = Pattern.compile(regEx);
	    Matcher matcher = pattern.matcher(pwd);
	    // 字符串是否与正则表达式相匹配
	    return matcher.matches();
	}
	
	/**
	 * 给字符串增加*星号
	 * @param str
	 * @param front 前面保留位数
	 * @param end	后面保留位数
	 * @return
	 */
	public static String secretStar(final String str,int front,int end){
		if(isNull(str)){
			return null;
		}
		String product = "";
		if(str.length() <= front){
			product = str+"******"+str.substring((str.length() - end));
		}else{
			product = str.substring(0,front)+"******"+str.substring((str.length() - end));
		}
		return product;
	}
	
	public static boolean checkMobilePhone(String phoneNum) {
		Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$");
		Matcher m = p.matcher(phoneNum);
		return m.matches();
	}

	/**
	 * 判断是否是数字
	 * @Title: isNumeric
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("-[0-9]+([0-9]+)?|[0-9]+([0-9]+)?");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * @author zhaotf
	 * @date 2018/08/31 上午 10:53
	 * @Description: 判断字符串是否为空
	 */
	public static boolean isEmptyStr(Object dateStr) {
		if (dateStr == null || "".equals(dateStr.toString())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获取长度为 6 的随机数字
	 * @return 随机数字
	 */
	public static String getNonce_str() {

		char[] nonceChars = new char[6];
		for (int index = 0; index < nonceChars.length; ++index) {
			nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
		}

		return new String(nonceChars);
	}
	
	
	/**
	 * 处理地区编码 用于GIS地图显示
	 */
	public static String formatAreaCode(Long l_areaCode) {
		String areaCode = String.valueOf(l_areaCode);
		/**
		 * 不足六位往后补零
		 */
		if(isNotNull(areaCode) && areaCode.length()%2==0) {
			if(areaCode.length() >= 6) {
				areaCode = areaCode.substring(0,6);
			}else if(areaCode.length() == 4) {
				areaCode = areaCode+"00";
			}else {
				areaCode =areaCode+"0000";
			}
		}else {
			areaCode = "370000";
		}
		return areaCode;
	}
	
	/**
     * 重命名，UUIU
     *
     * @param oleFileName
     * @return
     */
    public static String reloadFile(String oleFileName) {
        oleFileName = getFileName(oleFileName);
        if (StringUtil.isNull(oleFileName)) {
            return oleFileName;
        }
        //得到后缀
        if (oleFileName.indexOf(".") == -1) {
            //对于没有后缀的文件，直接返回重命名
            return UUID.randomUUID()+".zip";
        }
        String[] arr = oleFileName.split("\\.");
        // 根据uuid重命名图片
        String fileName = UUID.randomUUID() + "." + arr[arr.length - 1];
 
        return fileName;
    }
 
    /**
     * 把带路径的文件地址解析为真实文件名 /25h/upload/hc/1448089199416_06cc07bf-7606-4a81-9844-87d847f8740f.mp4 解析为 1448089199416_06cc07bf-7606-4a81-9844-87d847f8740f.mp4
     *
     * @param url
     */
    public static String getFileName(final String url) {
        if (StringUtil.isNull(url)) {
            return url;
        }
        String newUrl = url;
        newUrl = newUrl.split("[?]")[0];
        String[] bb = newUrl.split("/");
        String fileName = bb[bb.length - 1];
        return fileName;
    }

	/**
	 * 根据地区编号查询下级地区编号长度
	 * @param areaCode
	 * @return
	 */
	public static Integer getNextAreaLength(final Long areaCode){
		String area = String.valueOf(areaCode);
		Integer len = area.length();
		switch(len){
			case 2:
				len = 4;
				break;
			case 4:
				len = 6;
				break;
			case 6:
				len = 9;
				break;
			default:
				len =2;
		}
		return len;
	}
	/**
	 * 根据地区编号查询上级地区编号
	 */
	public static String supperAreaCode(String areaCode) {
		/**
		 * 不足六位往后补零
		 */
		if(isNotNull(areaCode)) {
			switch (areaCode.length()) {
				case 4:
					areaCode = areaCode.substring(0,2);
					break;
				case 6:
					areaCode = areaCode.substring(0,4);
					break;
				case 9:
					areaCode = areaCode.substring(0,6);
					break;
			}
		}
		return areaCode;
	}

	public static String getSHA256(String str) {
        MessageDigest messageDigest;
        String encodeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            encodeStr = byte2Hex(messageDigest.digest());
        } catch (Exception e) {
            System.out.println("getSHA256 is error" + e.getMessage());
        }
        return encodeStr;
    }
 
    public static String byte2Hex(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        String temp;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                builder.append("0");
            }
            builder.append(temp);
        }
        return builder.toString();
    }
    /**
     * 计算hash服务
     * @param index 索引
     * @param previousHash 前一个区块的hash值
     * @param timestamp 时间戳
     * @param data 数据
     * @return 当前hash
     */
    public static String calculateHash(long index, long timestamp, String data) {
        StringBuilder builder = new StringBuilder();
        builder.append(index).append(timestamp).append(data);
        return getSHA256(builder.toString());
    }
    /* 
     * 将时间转换为时间戳
     */    
    public static String dateToStamp(String s){
        String res = "";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date;
		try {
			date = simpleDateFormat.parse(s);
			long ts = date.getTime();
		    res = String.valueOf(ts);
		} catch (ParseException e) {
			e.printStackTrace();
		}
      
        return res;
    }
    
    /**
     * 获得不重复的集合
     * @param arr
     * @return
     */
    public static Object[] ifRepeat(Object[] arr){  
        //实例化一个set集合  
        Set set = new HashSet();  
        //遍历数组并存入集合,如果元素已存在则不会重复存入  
        for (int i = 0; i < arr.length; i++) {  
            set.add(arr[i]);  
        }  
        //返回Set集合的数组形式  
        return set.toArray();  
    } 
    
    /**
     * 使用 HashSet 将list数据 去重
     * @param list
     */
        public static List<Object> quChong(List<Object> list) {
            Iterator<Object> iterator = list.iterator();
            while (iterator.hasNext()) {
                // 获取循环的值
            	Object item = iterator.next();
                // 如果存在两个相同的值
                if (list.indexOf(item) != list.lastIndexOf(item)) {
                    // 移除最后那个相同的值
                    iterator.remove();
                }
            }
          	return list;
        }
    
    public static String getUUID() {
    	return UUID.randomUUID().toString().replaceAll("-", "");
    }
/*	public static void main(String[] args) {
		List<Object> list = new ArrayList<Object>()
		{{
		add(1);
		add(3);
		add(5);
		add(2);
		add(1);
		add(3);
		add(7);
		add(2);
		}};
        System.out.println("原集合:" + list);
        quChong(list);
	}*/
	
}
